//CUPPA:include=+
#include "../src/MiX/Tokenizer.h"
//CUPPA:include=-
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/TestAssert.h>

//CUPPA:namespace=+
//CUPPA:namespace=-

class TokenizerTest : public CppUnit::TestFixture {
  CPPUNIT_TEST_SUITE(TokenizerTest);
//CUPPA:suite=+
  CPPUNIT_TEST(testTokenizeBuffer);
  CPPUNIT_TEST(testTokenizeStream);
//CUPPA:suite=-
  CPPUNIT_TEST_SUITE_END();
private:

  // your stuff...
  static const char data_[];
  static const MiX::TokenType sequence_[];
public:

  virtual void setUp() { /* initialize */ }
  virtual void tearDown() { /* terminate */ }

//CUPPA:decl=+
  void testTokenizeBuffer() {
    MiX::Tokenizer<char> tokenizer;
    tokenizer.injectString(data_);
    MiX::XMLToken<char> tok;
    MiX::XMLToken<char> dmy;
    int n = 0;
    do{
      tokenizer.ejectToken(tok);
      CPPUNIT_ASSERT_EQUAL(sequence_[n],tok.getType());
      tokenizer.pushToken(tok);
      tokenizer.pushToken(dmy);
      tokenizer.ejectToken(dmy);
      tokenizer.ejectToken(tok);
      CPPUNIT_ASSERT_EQUAL(sequence_[n],tok.getType());
      ++n;
    }while(tok.getType()!=MiX::Token_null);
    tokenizer.injectString(data_);

    tokenizer.injectString(data_);
    n = 0;
    do{
      tokenizer.ejectToken(tok);
      CPPUNIT_ASSERT_EQUAL(sequence_[n],tok.getType());
      ++n;
    }while(tok.getType()!=MiX::Token_null);
  }
  void testTokenizeStream() {
    MiX::Tokenizer<char> tokenizer;
    std::istringstream ss(data_);
    tokenizer.injectStream(ss);
    MiX::XMLToken<char> tok;
    MiX::XMLToken<char> dmy;
    int n = 0;
    do{
      tokenizer.ejectToken(tok);
      //std::cout << n << std::endl;
      CPPUNIT_ASSERT_EQUAL(sequence_[n],tok.getType());
      tokenizer.pushToken(tok);
      tokenizer.pushToken(dmy);
      tokenizer.ejectToken(dmy);
      tokenizer.ejectToken(tok);
      CPPUNIT_ASSERT_EQUAL(sequence_[n],tok.getType());
      ++n;
    }while(tok.getType()!=MiX::Token_null);

    std::istringstream ss2(data_);
    tokenizer.injectStream(ss2);
    n = 0;
    do{
      tokenizer.ejectToken(tok);
      CPPUNIT_ASSERT_EQUAL(sequence_[n],tok.getType());
      ++n;
    }while(tok.getType()!=MiX::Token_null);
  }
//CUPPA:decl=-
};

//CUPPA:impl=+
const char TokenizerTest::data_[] = {
    "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
    "<TestSuite>"
    "<TestCase Name=\"testTokenize\"/>"
    "<TestCase Name=\"testPushEject\">"
    "  This is <b>TEST</b>  "
    "</TestCase>"
    "</TestSuite>"
    "\0"
  };
const MiX::TokenType TokenizerTest::sequence_[] = {
  //"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
  MiX::Token_lt,MiX::Token_question,MiX::Token_text,MiX::Token_space,
  MiX::Token_text,MiX::Token_eq,MiX::Token_dblquote,MiX::Token_text,
  MiX::Token_dblquote,MiX::Token_space,MiX::Token_text,
  MiX::Token_eq,MiX::Token_dblquote,MiX::Token_text,MiX::Token_hyphen,
  MiX::Token_text,MiX::Token_dblquote,MiX::Token_question,MiX::Token_gt,
  //"<TestSuite>"
  MiX::Token_lt,MiX::Token_text,MiX::Token_gt,
  //"<TestCase Name=\"testTokenize\"/>"
  MiX::Token_lt,MiX::Token_text,MiX::Token_space,MiX::Token_text,
  MiX::Token_eq,MiX::Token_dblquote,MiX::Token_text,
  MiX::Token_dblquote,MiX::Token_slash,MiX::Token_gt,
  //"<TestCase Name=\"testPushEject\">" 
  MiX::Token_lt,MiX::Token_text,MiX::Token_space,MiX::Token_text,
  MiX::Token_eq,MiX::Token_dblquote,MiX::Token_text,
  MiX::Token_dblquote,MiX::Token_gt,
  //"  This is <b>TEST</b>  "
  MiX::Token_space,MiX::Token_space,MiX::Token_text,MiX::Token_space,
  MiX::Token_text,MiX::Token_space,MiX::Token_lt,MiX::Token_text,
  MiX::Token_gt,MiX::Token_text,MiX::Token_lt,MiX::Token_slash,
  MiX::Token_text,MiX::Token_gt,MiX::Token_space,MiX::Token_space,
  //"</TestCase>"
  MiX::Token_lt,MiX::Token_slash,MiX::Token_text,MiX::Token_gt,
  //"</TestSuite>"
  MiX::Token_lt,MiX::Token_slash,MiX::Token_text,MiX::Token_gt,
  MiX::Token_null
};
//CUPPA:impl=-

CPPUNIT_TEST_SUITE_REGISTRATION(TokenizerTest);
